﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Common.MessageHelp;
using RosSharp.RosBridgeClient;
using RosSharpHelp.Messages;

namespace BoardController.Extend
{
    public static class RosSocketExtend
    {
        public static string Advertise(this RosSocket rosSocket, Type type, string topic)
        {
            Type typeRosSocket = typeof(RosSocket);

            Type[] types = { typeof(string) };
            MethodInfo methodAdvertise = typeRosSocket.GetMethod(nameof(RosSocket.Advertise), types);
            MethodInfo miConstructed = methodAdvertise.MakeGenericMethod(type);
            object result = miConstructed.Invoke(rosSocket, new object[1] { topic });
            string id = result as string;
            return id;
        }

       

        public static string Subscribe(this RosSocket rosSocket, Type type, string topic,  int throttle_rate = 0, int queue_length = 1, int fragment_size = int.MaxValue, string compression = "none") 
        {
           
            //反射得到泛型 SubscriptionHandlerHelp<T>
            Type d1 = typeof(SubscriptionHandlerHelp<>);
            Type[] typeArgs = { type };
            Type constructed = d1.MakeGenericType(typeArgs);
            object subscriptionHandlerHelp = Activator.CreateInstance(constructed);
            //反射得到泛型的委托SubscriptHandler
            FieldInfo filedSubscriptHandler = constructed.GetField(nameof(SubscriptionHandlerHelp<Message>.SubscriptHandler), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            object subscriptHandler = filedSubscriptHandler.GetValue(subscriptionHandlerHelp);

            //反射得到泛型的RosSocket的泛型方法Subscribe
            Type typeRosSocket = typeof(RosSocket);
            MethodInfo methodSubscribee = typeRosSocket.GetMethod(nameof(RosSocket.Subscribe), BindingFlags.NonPublic | BindingFlags.Instance);
            MethodInfo miConstructed = methodSubscribee.MakeGenericMethod(type);
            //将参数代入泛型方法Subscribe
            object result = miConstructed.Invoke(rosSocket, new object[6] { topic, subscriptHandler, throttle_rate, queue_length, fragment_size, compression });
            string id = result as string;
            return id;
        }

        public static void SubscriptionHandlerAction(string message, ISerializer serializer)
        {
            RosTopicMessage rosTopicMessage = new RosTopicMessage()
            {
                Content = message,
                Serializer = serializer,
            };
            MessageAggregator<RosTopicMessage>.Publish(rosTopicMessage);
        }



    }
}
